typedef struct abt_declaration_list_ * abt_declaration_list;
typedef struct abt_declaration_ * abt_declaration;
typedef struct abt_var_ * abt_var;
typedef struct abt_const_ * abt_const;
typedef struct abt_argument_list_ * abt_argument_list;
typedef struct abt_exp_ * abt_exp;
typedef struct abt_explist_ * abt_explist;
typedef struct abt_oper_ * abt_oper;
typedef struct abt_stmt_ * abt_stmt;
typedef struct abt_stmtlist_ * abt_stmtlist;
typedef struct abt_dec_ * abt_dec;
typedef struct abt_declist_ *abt_declist;
typedef struct abt_declist_ *abt_declist;

enum abt_var_type{
    ABT_VAR_SAVED,
    ABT_VAR_BASE,
    ABT_VAR_FIELD,
    ABT_VAR_ARRAY,
    ABT_VAR_FUNCTION,
    ABT_VAR_VOID
};

enum abt_exp_type{
    ABT_EXP_SAVED,
    ABT_EXP_ASSGIN,
    ABT_EXP_OPER,
    ABT_EXP_CONST,
    ABT_EXP_VAR,
    ABT_EXP_CALL
};

enum abt_const_type{
    ABT_CONST_SAVED,
    ABT_CONST_NUM
};

enum abt_oper_type{
    ABT_OPER_SAVED,
    ABT_OPER_ADD,
    ABT_OPER_MINUS,
    ABT_OPER_STAR,
    ABT_OPER_DIV,
    ABT_OPER_EQUAL,
    ABT_OPER_NOT_EQUAL,
    ABT_OPER_GREAT,
    ABT_OPER_LESS,
    ABT_OPER_GREAT_EQUAL,
    ABT_OPER_LESS_EQUAL
};

enum abt_stmt_type{
    ABT_STMT_COMPOUND,
    ABT_STMT_EXPRESSION,
    ABT_STMT_SELECTION,
    ABT_STMT_ITERATION,
    ABT_STMT_JUMP
};

enum abt_iter_stmt_type{
    ABT_ITER_WHILE,
    ABT_ITER_FOR
};

enum abt_jump_stmt_type{
    ABT_JUMP_RETURN,
    ABT_JUMP_GOTO,
    ABT_JUMP_BREAK
};

enum abt_dec_type{
    ABT_DEC_SAVED,
    ABT_DEC_ARRAY,
    ABT_DEC_FUNCTION,
    ABT_DEC_SPECIFIER,
    ABT_DEC_STRUCT,
    ABT_DEC_VOID,
    ABT_DEC_INT
};

typedef struct abt_var_{
    int type;
    char * sym;
    union{
        struct{
            abt_exp idx_exp;
        }array_info;
        struct{
            char * dsym;
        }field_info;
    } info;
}abt_var_;

typedef struct abt_exp_{
    int type;
    union{
        struct{
            abt_var var;
            abt_exp exp;
        }assgin_exp;

        struct{
            abt_var var;
        }var_exp;

        struct{
            abt_const cst;
        }const_exp;
        
        struct{
            abt_oper op;
            abt_exp left;
            abt_exp right;
        }oper_exp;
        
        struct{
            abt_var var;
            abt_explist explist;
        }call_exp;
        
    } exp;
}abt_exp_;

typedef struct abt_explist_{
    abt_exp exp;
    abt_explist explist;
}abt_explist_;

typedef struct abt_const_{
    int type;
    union{
        int num_const;
    }cst;
}abt_const_;

typedef struct abt_oper_{
    int type;
}abt_oper_;

typedef struct abt_stmt_{
    int type;
    union{
        struct{
            abt_stmtlist stmtlist;
        }compound_stmt;
        struct{
            abt_exp exp;
        }expression_stmt;
        struct{
            abt_exp exp;
            abt_stmt tstmt;
            abt_stmt fstmt;
        }selection_stmt;
        struct{
            int type;
            union{
                abt_exp while_exp;
                struct{
                    abt_exp exp1;
                    abt_exp exp2;
                    abt_exp exp3;
                }for_exp;
            }exp;
            abt_stmt stmt;
        }iteration_stmt;
        struct{
            int type;
            union{
                abt_exp exp;
            }args;
        }jump_stmt;
    }stmt;
}abt_stmt_;

typedef struct abt_dec_{
    int type;
    char *sym;
    union{
        struct{
            int size;
            int etype;
            char *ssym;
            abt_declist sdeclist;
        }array_info;
        struct{
            int rtype;
            abt_declist arglist;
            abt_stmt cstmt;
            char *ssym;
            abt_declist sdeclist;          
        }function_info;
        struct{
            char *ssym;
            abt_declist sdeclist;
        }struct_info;
    }info;
}abt_dec_;

typedef struct abt_declist_{
    abt_dec dec;
    abt_declist declist;
}abt_declist_;

typedef struct abt_stmtlist_{
    abt_stmt stmt;
    abt_stmtlist stmtlist;
}abt_stmtlist_;

abt_oper abt_op(int type);

abt_const abt_num_const(int num);

abt_var abt_base_var(char *sym);
abt_var abt_field_var(char *sym,char *dsym);
abt_var abt_array_var(char *sym,abt_exp exp);

abt_exp abt_assgin_exp(abt_var var,abt_exp exp);
abt_exp abt_oper_exp(abt_oper op,abt_exp left,abt_exp right);
abt_exp abt_var_exp(abt_var var);
abt_exp abt_const_exp(abt_const cst);
abt_exp abt_call_exp(abt_var var,abt_explist explist);

abt_stmt abt_expression_stmt(abt_exp exp);
abt_stmt abt_for_stmt(abt_exp exp1,abt_exp exp2,abt_exp exp3,abt_stmt stmt);
abt_stmt abt_while_stmt(abt_exp exp,abt_stmt stmt);
abt_stmt abt_selection_stmt(abt_exp exp,abt_stmt tstmt,abt_stmt fstmt);
abt_stmt abt_return_stmt(abt_exp exp);
abt_stmt abt_break_stmt();
abt_stmt abt_goto_stmt();

abt_dec abt_int_dec(char *sym);
abt_dec abt_void_dec(char *sym);
abt_dec abt_array_dec(char *sym,int size,int etype,char *ssym,abt_declist declist);
abt_dec abt_function_dec(char *sym,int rtype,abt_declist arglist,abt_stmt cstmt,char *ssym,abt_declist declist);
abt_dec abt_struct_dec(char *sym,char *ssym,abt_declist declist);
abt_declist abt_dec_list(abt_dec dec,abt_declist declist);
abt_explist abt_exp_list(abt_exp exp,abt_explist explist);

abt_stmtlist abt_stmt_list(abt_stmt stmt,abt_stmtlist stmtlist);

void log_abt(abt_declist declist);



